/**
 * 全局核心配置方法
 */
import CryptoJS from 'crypto-js'

// 是否开启debug
// 开启后优先使用$debugConfig中的配置
const $debug = true

// 默认配置
const $config = {
	// 系统名称
	name: 'DarkUni系统',
	// 安全中心
	// 生产环境下请勿轻易修改，可能会导致用户登出
	safety: {
		// 用户信息存储key
		userStorage: 'dkuni_user_info',
		// 加密认证（弱验证）
		secret: 'jc0pswjq4wcz2mbj',
		// HBuilder版本（APP更新相关）
		hbuilder: '4.24',
	},
	// mock配置，只有使用getApiServerUrl方法才会有效
	// 可以在生产环境下生效
	mock: {
		// 是否开启
		open: true,
		// mock忽略的地址，必须输入带前缀的完整地址（不包括域名）
		// 示例: ['/api/app_v1/Account/Login', '/api/app_v1/Account/UserInfo'],
		ignore: [],
	},
	// 请求服务器
	apiServer: {
		// 默认服务器
		default: '',
		// 更新服务器
		update: '',
	},
	// 页面设置
	pages: {
		// 登录页面
		login: {
			// 登录方式类型，可选：both、mobile、account
			type: 'both',
			// 右下角显示，可选：version（显示内置版本号）、任意自定义文字。留空不显示
			copyright: 'version',
		},
	},
	// APP端配置
	// 仅在打包app时生效
	app: {
		// APP签名（留空不验证)
		signature: {
			// 安卓
			android: '',
			// IOS
			ios: '',
		},
		// 是否允许在模拟器中运行
		runInSimulator: true,
	},
	// 页面设置
	pages: {
		// 登录页面
		login: {
			// 登录方式类型，可选：both、mobile、account
			type: 'both',
			// 右下角显示，可选：version（）、任意自定义文字。留空不显示
			copyright: 'version',
		},
	},
}

// 调试模式配置
// 配置项字段需要与$config中的对应，当开启$debug后，将会覆盖默认配置
const $debugConfig = {
	apiServer: {
		default: 'http://localhost:8100',
		update: '',
	},
}

/**
 * 自动配置取值
 *
 * @param {string} key 对应键名
 * @returns
 */
function getConfigValue(key) {
	let source = $debug ? $debugConfig : $config
	let value = key.split('.').reduce((o, k) => (o || {})[k], source)
	if (value === undefined && $debug) {
		value = key.split('.').reduce((o, k) => (o || {})[k], $config)
	}
	return value
}

/**
 * 获取用户信息存储key
 *
 * @returns string
 */
export function getUserStorageKey() {
	return getConfigValue('safety.userStorage')
}

/**
 * 获取当前登录用户名（无验证）
 *
 * @returns string
 */
export function getLoginName() {
	const data = uni.getStorageSync(getUserStorageKey())
	if (data) {
		return data.LoginName || ''
	}
	return ''
}

/**
 * 获取当前登录用户Token（无验证）
 *
 * @returns string
 */
export function getLoginToken() {
	const data = uni.getStorageSync('zwst_user_info')
	if (data) {
		return data.Token || ''
	}
	return ''
}

/**
 * 获取系统名称
 *
 * @returns string
 */
export const getSystemConfigName = () => {
	return getConfigValue('name')
}

/**
 * 获取基座版本
 *
 * @returns number
 */
export const getBaseVersion = () => {
	return getConfigValue('baseVersion')
}

/**
 * 获取API服务器访问地址
 *
 * @param {string} uri 相对路径
 * @param {string} prefix 前置路径
 * @returns string
 */
export const getApiServerUrl = (uri = '', prefix = 'api/') => {
	if (uri.indexOf('/') === 0) {
		uri = uri.slice(1)
	}
	let api = getConfigValue('apiServer.default')
	if (getConfigValue('mock.open')) {
		const ignore = getConfigValue('mock.ignore')
		// 开启mock判定
		if (!ignore.includes('/' + prefix + uri)) {
			api = ''
		}
	}
	return api + '/' + prefix + uri
}

/**
 * 获取APP更新服务器访问地址
 *
 * @param {string} uri 相对路径
 * @param {string} prefix 前置路径
 * @returns string
 */
export const getAppUpdateUrl = (uri = '', prefix = '') => {
	if (uri.indexOf('/') === 0) {
		uri = uri.slice(1)
	}
	return getConfigValue('apiServer.update') + '/' + prefix + uri
}

/**
 * 获取登录页类型
 *
 * @returns string
 */
export const getLoginPageType = () => {
	return getConfigValue('pages.login.type')
}

/**
 * 获取登录页版权信息
 *
 * @returns string
 */
export const getLoginPageCopyright = () => {
	return getConfigValue('pages.login.copyright')
}

/**
 * AES对称加密 （ECB模式）
 *
 * @param {string} str 明文参数
 * @returns string base64密文
 */
export const aesEncrypt = (str) => {
	const key = CryptoJS.enc.Utf8.parse(getConfigValue('safety.secret'))
	str = CryptoJS.enc.Utf8.parse(str)
	const encrypt = CryptoJS.AES.encrypt(str, key, {
		iv: [],
		mode: CryptoJS.mode.ECB, //AES加密模式
		padding: CryptoJS.pad.Pkcs7, //填充方式，这里后端是5 也可以用
	})
	return CryptoJS.enc.Base64.stringify(encrypt.ciphertext) //返回base64格式密文
}

/**
 * AES对称解密 （ECB模式，key为项目secret）
 *
 * @param {string} str 密文参数
 * @returns string
 */
export const aesDecrypt = (str) => {
	try {
		const key = CryptoJS.enc.Utf8.parse(getConfigValue('safety.secret'))
		const decrypt = CryptoJS.AES.decrypt(str, key, {
			iv: [],
			mode: CryptoJS.mode.ECB, //AES加密模式
			padding: CryptoJS.pad.Pkcs7, //填充方式，这里后端是5 也可以用
		})
		return CryptoJS.enc.Utf8.stringify(decrypt).toString()
	} catch (e) {
		return ''
	}
}

/**
 * App启动检测
 *
 * @returns Promise
 */
export function onLaunchCheck() {
	return new Promise(async (resolve, reject) => {
		// #ifdef APP-PLUS
		if (!getConfigValue('app.runInSimulator') && plus.navigator.isSimulator()) {
			return reject('请勿在模拟器中运行')
		}
		const platform = uni.getSystemInfoSync().platform
		const sign = plus.navigator.getSignature()
		if (platform === 'ios') {
			const iosSignature = getConfigValue('app.signature.ios')
			if (iosSignature && sign !== iosSignature) {
				return reject('应用数据损坏，请卸载APP后访问AppStore重新安装')
			}
		} else {
			const androidSignature = getConfigValue('app.signature.android')
			if (androidSignature && sign !== androidSignature) {
				return reject('应用数据损坏，请尝试重新安装APP')
			}
		}
		resolve(true)
		// #endif
		// #ifndef APP-PLUS
		resolve(true)
		// #endif
	})
}
